package com.itheima.stream;

import java.io.*;

/**
 * 需求：将E:/什么是幸福.mp4拷贝到E:/什么是幸福1.mp4
 * 步骤：
 * --1. 创建一个字节输入流对象FileInputStream fis，构造方法中绑定要拷贝的文件
 * --2. 创建一个字节输出流对象FileOutputStream fos，构造方法中绑定要写入数据的文件
 * ---考虑一次读一个字节写一个字节------------------------
 * -- 大量的磁盘访问是非常慢的，所以，一次读一个字节写一个字节，效率非常低，低到无法使用
 * ---考虑一次读多个字节写多个字节------------------------
 * --3. 开始while循环，使用字节输入流对象fis中的read方法读取文件
 * --4. 使用字节输出流对象fos中的write方法，把读取到的字节写入到文件中
 * --5. 退出while循环，关闭流对象
 *
 * 补充知识：System类
 * 获取系统当前的毫秒值
 * long System.currentTimeMillis()
 *
 */
public class FileCopyPractice {
    public static void main(String[] args) throws IOException {
        //先记录一下当前的系统时间start （毫秒）
        long start = System.currentTimeMillis();
        test4();//计算该方法的耗时
        //再记录一下当前的系统时间end
        long end = System.currentTimeMillis();
        //输出end-start就是耗时
        System.out.println("耗时："+(end-start));
    }
    //使用自己缓冲流一次读写取8kb个字节，
    //耗时：262ms
    private static void test4() throws IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E:/什么是幸福.mp4"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E:/什么是幸福4.mp4"));
        //定义一个变量 len 记录每次读到的字节的个数
        int len;
        byte[] buffer = new byte[1024*8];//8kb-->8192--相对比较高 16kb
        //3. 开始while循环，使用字节输入流对象fis中的read方法读取文件
        while((len = bis.read(buffer)) != -1){
            //4. 使用字节输出流对象fos中的write方法，把读取到的字节写入到文件中
            bos.write(buffer,0,len);
        }
        //5. 退出while循环，关闭流对象
        bos.close();
        bis.close();
    }
    //一次读取8kb个字节，
    //耗时：209,效率提高1k倍
    private static void test2() throws IOException {
        //1. 创建一个字节输入流对象FileInputStream fis，构造方法中绑定要拷贝的文件
        FileInputStream fis = new FileInputStream("E:/什么是幸福.mp4");
        //2. 创建一个字节输出流对象FileOutputStream fos，构造方法中绑定要写入数据的文件
        FileOutputStream fos = new FileOutputStream("E:/什么是幸福2.mp4");
        //定义一个变量 len 记录每次读到的字节的个数
        int len;
        byte[] buffer = new byte[1024*8];//8kb-->8192--相对比较高 16kb
        //3. 开始while循环，使用字节输入流对象fis中的read方法读取文件
        while((len = fis.read(buffer)) != -1){
            //4. 使用字节输出流对象fos中的write方法，把读取到的字节写入到文件中
            fos.write(buffer,0,len);
        }
        //5. 退出while循环，关闭流对象
        fos.close();
        fis.close();


    }


    //Ctrl+Alt+M  --> 抽取方法
    //一次读写一个字节
    //耗时：206692
    private static void test1() throws IOException {
        //1. 创建一个字节输入流对象FileInputStream fis，构造方法中绑定要拷贝的文件
        FileInputStream fis = new FileInputStream("E:/什么是幸福.mp4");
        //2. 创建一个字节输出流对象FileOutputStream fos，构造方法中绑定要写入数据的文件
        FileOutputStream fos = new FileOutputStream("E:/什么是幸福1.mp4");
        //定义一个变量 b 记录每次读到的字节的值
        int b;
        //3. 开始while循环，使用字节输入流对象fis中的read方法读取文件
        while((b = fis.read()) != -1){
            //4. 使用字节输出流对象fos中的write方法，把读取到的字节写入到文件中
            fos.write(b);
        }
        //5. 退出while循环，关闭流对象
        fos.close();
        fis.close();
    }

    //使用字节缓冲流一次读写一个字节
    //耗时：4676ms，性能比原始的字节流提高50倍
    private static void test3() throws IOException {
        //1. 创建一个字节缓冲输入流对象BufferedInputStream bis，对FileInputStream fis进行包装（装饰器设计模式），构造方法中绑定要拷贝的文件
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E:/什么是幸福.mp4"));
        //2. 创建一个字节缓冲输出流对象BufferedOutputStream bos，对FileOutputStream fos进行包装（装饰器设计模式），构造方法中绑定要写入数据的文件
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E:/什么是幸福3.mp4"));
        //定义一个变量 b 记录每次读到的字节的值
        int b;
        //3. 开始while循环，使用字节输入流对象fis中的read方法读取文件
        while((b = bis.read()) != -1){
            //4. 使用字节输出流对象fos中的write方法，把读取到的字节写入到文件中
            bos.write(b);
        }
        //5. 退出while循环，关闭流对象
        bos.close();
        bis.close();
    }
}
